<?php

// 用户控制器

namespace app\api\controller;

use app\api\controller\Base;
use app\api\model\Node;
use app\api\model\Shop;
use app\api\model\Link;
use app\api\model\Flow;
use app\api\model\Signed;
use app\api\model\Invite;
use app\api\model\Config;
use app\api\model\Device;
use app\api\model\Service;
use app\api\model\Feedback;
use app\api\model\VerifyCode;
use app\api\model\Ipblacklist;
use app\api\model\PaymentOrder;
use app\api\model\User as UserModel;
use think\Validate;
use think\facade\Cache;
use think\facade\Request;
use think\helper\Hash;

class User extends Base
{

    // Redis缓存驱动
    public $redis;

    public function initialize()
    {
        parent::initialize();
        // redis连接缓存驱动
        $this->redis = Cache::store('redis');

        vpn_error_log(1, input());
        vpn_error_log(2, $this->request->header());

        // 令牌
        $token = $this->redis->get('token');

        $this->ip = $this->request->ip();

        $this->uid = $this->request->header('uid', '');
        $this->model = $this->request->header('model', '');
        $this->device = $this->request->header('device', '');
        $this->system = $this->request->header('system', '');
        $this->version = $this->request->header('version', '');
        $this->channel = $this->request->header('channel', '');
        $this->reqtime = $this->request->header('reqtime', '');
        $this->sign = $this->request->header('sign', '');
        $this->usersign = $this->request->header('usersign', '');

        $this->expire = strtotime(date('Y-m-d', strtotime('+1 day'))) - time();

        $this->user = UserModel::where(['id' => $this->uid, 'status' => 1])->find();

        /*
        $user_info_id = 'vpn_user_info_id_' . $this->uid;
        $now_user_info_id = $this->redis->get($user_info_id);
        if ($now_user_info_id) {
            $this->user = $now_user_info_id;
        } else {
            $this->user = UserModel::where(['id' => $this->uid, 'status' => 1])->find();
            $this->redis->set($user_info_id, $this->user, $this->expire);
        }
        */

        $sign = md5($this->reqtime . $token['value']);
        if ($this->reqtime < time() - 300 || $this->reqtime > time() + 300) {
            json(['code' => 0, 'msg' => '发送请求时间错误'])->send();
            exit;
        }
        if ($sign != $this->sign) {
            json(['code' => 0, 'msg' => '系统sign错误'])->send();
            exit;
        }

        if (!in_array($this->request->action(), ['login', 'register'])) {
            if ($this->user) {
                $u_sign = md5($this->reqtime . $this->user['token']);
                if ($u_sign != $this->usersign) {
                    json(['code' => 2000, 'msg' => '用户sign错误'])->send();
                    exit;
                }
            } else {
                json(['code' => 2000, 'msg' => '用户sign错误'])->send();
                exit;
            }
        }

        // 用户在线
        $this->online();

        // ip黑名单
        $this->ipblack();
    }

    /**
     * 登录
     */
    public function login()
    {
        try {
            // 表单数据
            $data = $this->request->post();
            // 验证
            $validate = Validate::make([
                'type|类型' => 'require|in:0,1',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            if (empty($this->device)) {
                return ['code' => 0, 'msg' => '设备不能为空'];
            }

            // 游客登录
            if ($data['type'] == 0) {

                $user = UserModel::where(['device' => $this->device])->order(['id' => 'desc'])->find();
                if ($user) {
                    $res['uid'] = $user['id'];
                    $res['username'] = $user['username'];
                    $res['nickname'] = $user['nickname'];
                    $res['email'] = $user['email'];
                    $res['mobile'] = $user['mobile'];
                    $res['money'] = $user['money'];
                    $res['device'] = $user['device'];
                    $res['system'] = $user['system'];
                    $res['channel'] = $user['channel'];
                    $res['invite'] = $user['invite'];
                    $res['bind_invite'] = $user['bind_invite'];
                    $res['rank'] = $user['rank'];
                    $res['is_vip'] = $user['is_vip'];
                    $res['expire_time'] = $user['expire_time'];
                    $res['high_expire_time'] = $user['high_expire_time'];
                    $res['token'] = $user['token'];

                    $user_update['id'] = $user['id'];
                    $user_update['last_login_time'] = time();
                    $user_update['last_login_ip'] = request()->ip(1);
                    UserModel::update($user_update);

                    $this->addDevice($res);
                    $this->deleteCache(1, $res['uid']);
                    return ['code' => 1, 'msg' => '成功', 'data' => $res];
                } else {

                    $invite = isset($data['invite']) ? $data['invite'] : '';
                    if ($invite) {
                        $user_invite = UserModel::where(['invite' => $invite])->find();
                        $invite = isset($user_invite['invite']) ? $invite : '';
                    }

                    $register_invite = random(6, 3);
                    $register_invite_info = UserModel::where(['invite' => $register_invite])->find();
                    if ($register_invite_info) {
                        $register_invite = random(6, 3);
                        $register_invite_info = UserModel::where(['invite' => $register_invite])->find();
                        if ($register_invite_info) {
                            return ['code' => 0, 'msg' => '稍后再试1'];
                        }
                    }

                    $uid = UserModel::max('id');
                    $uid = $uid + 1;
                    $pwd = random(8);

                    $res['username'] = 'user' . $uid;
                    $res['nickname'] = '';
                    $res['email'] = '';
                    $res['mobile'] = '';
                    $res['money'] = 0;
                    $res['device'] = $this->device;
                    $res['system'] = $this->system;
                    $res['channel'] = $this->channel;
                    $res['invite'] = $register_invite;
                    $res['bind_invite'] = $invite;
                    $res['rank'] = 0;
                    $res['is_vip'] = 0;
                    $res['expire_time'] = time();
                    $res['high_expire_time'] = time();
                    $res['token'] = md5(random(8));

                    $res['role'] = 17;
                    $res['status'] = 1;
                    $res['last_login_time'] = time();
                    $res['last_login_ip'] = request()->ip(1);
                    $res['create_time'] = time();
                    $res['update_time'] = time();
                    $res['password'] = Hash::make((string)$pwd);

                    // 1个ip在1个小时内最多注册三个帐号
                    $register_ip = 'vpn_register_' . request()->ip(1);
                    $now_register_ip = $this->redis->get($register_ip);
                    if ($now_register_ip) {
                        $this->redis->set($register_ip, $now_register_ip + 1, 3600);
                    } else {
                        $this->redis->set($register_ip, 1, 3600);
                    }
                    if ($now_register_ip >= 3) {
                        return ['code' => 0, 'msg' => '稍后再试2'];
                    }

                    // 1个设备5秒注册一次（拦截）
                    $register_device = 'vpn_register_device_' . $this->device;
                    $now_register_device = $this->redis->get($register_device);
                    if ($now_register_device) {
                        return ['code' => 0, 'msg' => '稍后再试3'];
                    } else {
                        $this->redis->set($register_device, 1, 5);
                    }

                    if ($user = UserModel::create($res)) {

                        if ($invite) {
                            $map = [];
                            $map[] = ['name', '=', 'invite_reward'];
                            $map[] = ['group', '=', 'vpn_config'];
                            $invite_reward = Config::where($map)->value('value');

                            $invite_data['uid'] = $user_invite['id'];
                            $invite_data['reg_uid'] = $user['id'];
                            $invite_data['invite_reward'] = $invite_reward;
                            $invite_data['invite'] = $invite;
                            $invite_data['device'] = $this->device;
                            $invite_data['system'] = $this->system;
                            $invite_data['version'] = $this->version;
                            $invite_data['channel'] = $this->channel;
                            $invite_data['ip'] = $this->ip;
                            $invite_data['remark'] = '';
                            $invite_data['status'] = 1;
                            $invite_data['create_time'] = time();
                            $invite_data['update_time'] = time();
                            $invite_create = Invite::create($invite_data);
                            if ($invite_create) {
                                UserModel::where('id', $user_invite['id'])
                                    ->inc('money', $invite_reward)
                                    ->update(['update_time' => time()]);
                            }
                        }

                        $res['uid'] = $user['id'];
                        $res['invite'] = $register_invite;
                        $res['bind_invite'] = $invite;
                        $res['password'] = $pwd;
                        unset($res['role']);
                        unset($res['status']);
                        unset($res['last_login_time']);
                        unset($res['last_login_ip']);
                        unset($res['create_time']);
                        unset($res['update_time']);
                        // unset($res['password']);

                        $this->addDevice($res);
                        $this->deleteCache(1, $res['uid']);
                        return ['code' => 1, 'msg' => '成功', 'data' => $res];
                    } else {
                        return ['code' => 0, 'msg' => '注册信息更新失败，请重新注册'];
                    }
                }
            }

            // 帐号登录
            if ($data['type'] == 1) {

                $validate = Validate::make([
                    'username|帐号' => 'require',
                    'password|密码' => 'require',
                ]);

                if (!$validate->check($data)) {
                    return ['code' => 0, 'msg' => $validate->getError()];
                }

                $username = trim($data['username']);
                $password = trim($data['password']);

                // 匹配登录方式
                if (preg_match("/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/", $username)) {
                    // 邮箱登录
                    $map['email'] = $username;
                } elseif (preg_match("/^1\d{10}$/", $username)) {
                    // 手机号登录
                    $map['mobile'] = $username;
                } else {
                    // 用户名登录
                    $map['username'] = $username;
                }

                $map['status'] = 1;

                // 查找用户
                $user = UserModel::where($map)->find();
                if (!$user) {
                    return ['code' => 0, 'msg' => '用户不存在或被禁用'];
                } else {

                    if (!Hash::check((string)$password, $user['password'])) {
                        return ['code' => 0, 'msg' => '账号或者密码错误'];
                    } else {
                        $user_update['id'] = $user['id'];
                        $user_update['last_login_time'] = time();
                        $user_update['last_login_ip'] = request()->ip(1);
                        $user_update['is_vip'] = 1;
                        // $user_update['token'] = md5(random(8));

                        if (UserModel::update($user_update)) {
                            $res['uid'] = $user['id'];
                            $res['username'] = $user['username'];
                            $res['nickname'] = $user['nickname'];
                            $res['email'] = $user['email'];
                            $res['mobile'] = $user['mobile'];
                            $res['money'] = $user['money'];
                            $res['device'] = $this->device;
                            $res['system'] = $this->system;
                            $res['channel'] = $this->channel;
                            $res['invite'] = $user['invite'];
                            $res['bind_invite'] = $user['bind_invite'];
                            $res['rank'] = $user['rank'];
                            $res['is_vip'] = 1;
                            $res['expire_time'] = $user['expire_time'];
                            $res['high_expire_time'] = $user['high_expire_time'];
                            $res['token'] = $user['token'];

                            $this->addDevice($res);
                            $this->deleteCache(1, $res['uid']);
                            return ['code' => 1, 'msg' => '成功', 'data' => $res];
                        } else {
                            return ['code' => 0, 'msg' => '登录信息更新失败，请重新登录'];
                        }
                    }
                }
            }
        } catch (\Exception $e) {
            vpn_error_log(110000, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 获取用户信息
     */
    public function info()
    {
        try {
            $res['uid'] = $this->user['id'];
            $res['username'] = $this->user['username'];
            $res['nickname'] = $this->user['nickname'];
            $res['email'] = $this->user['email'];
            $res['mobile'] = $this->user['mobile'];
            $res['money'] = $this->user['money'];
            $res['device'] = $this->user['device'];
            $res['system'] = $this->user['system'];
            $res['channel'] = $this->user['channel'];
            $res['invite'] = $this->user['invite'];
            $res['bind_invite'] = $this->user['bind_invite'];
            $res['rank'] = $this->user['rank'];
            $res['is_vip'] = $this->user['is_vip'];
            $res['expire_time'] = $this->user['expire_time'];
            $res['high_expire_time'] = $this->user['high_expire_time'];
            $res['token'] = $this->user['token'];

            $device = Device::where(['uid' => $this->user['id']])
                ->limit(3)
                ->order(['update_time' => 'desc'])
                ->select();

            if ($device) {
                $device = $device->toArray();
                $all_device = array_column($device, 'device');
                if (!in_array($this->device, $all_device)) {
                    return ['code' => 2000, 'msg' => '请重新登录'];
                }
            }

            $map1 = [
                ['create_time', '>', strtotime(date('Y-m-d'))],
                ['device', '=', $this->device],
            ];
            $map2 = [
                ['create_time', '>', strtotime(date('Y-m-d'))],
                ['uid', '=', $this->uid],
            ];
            $signed = Signed::whereOr([$map1, $map2])->find();
            if ($signed) {
                $signed = 1;
            } else {
                $signed = 0;
            }

            $resdata['user'] = $res;
            $resdata['device'] = $device;
            $resdata['signed'] = $signed;

            return ['code' => 1, 'msg' => '成功', 'data' => $resdata];
        } catch (\Exception $e) {
            vpn_error_log(110002, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 注册
     */
    public function register()
    {
        try {
            // 表单数据
            $data = $this->request->post();
            // 验证
            $validate = Validate::make([
                'type|类型' => 'require|in:0,1,2',
                'username|用户名' => 'requireIf:type,2|alphaNum|length:2,32|unique:admin_user',
                'password|密码' => 'require|length:6,20',
                'email|邮箱' => 'requireIf:type,0|email|unique:admin_user',
                'mobile|手机号' => 'requireIf:type,1|regex:^1\d{10}|unique:admin_user',
                'verification_code|验证码' => 'length:1,20',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            if ($data['type'] == 0 || $data['type'] == 1) {

                $validate = Validate::make([
                    'verification_code|验证码' => 'require|length:1,20',
                ]);

                if (!$validate->check($data)) {
                    return ['code' => 0, 'msg' => $validate->getError()];
                }

                $email_mobile = $data['type'] == 1 ? $data['mobile'] : $data['email'];

                $verify = VerifyCode::where(['verification_code' => $data['verification_code'], 'email_mobile' => $email_mobile, 'status' => 1])->find();
                if (!$verify || $verify['timeout'] + $verify['create_time'] < time()) {
                    return ['code' => 0, 'msg' => '验证码不存在或验证码过期'];
                }
            }

            $user = UserModel::where(['device' => $this->device])->order(['id' => 'desc'])->find();
            if ($user) {
                if ($user['email'] && $data['type'] == 0) {
                    return ['code' => 0, 'msg' => '设备已经注册邮箱信息，请重新登录'];
                }
                if ($user['mobile'] && $data['type'] == 1) {
                    return ['code' => 0, 'msg' => '设备已经注册手机号信息，请重新登录'];
                }
            } else {
                return ['code' => 0, 'msg' => '设备信息有误'];
            }

            $invite = isset($data['invite']) ? $data['invite'] : '';
            if ($invite) {
                $user_invite = UserModel::where(['invite' => $invite])->find();
                $invite = isset($user_invite['invite']) ? $invite : '';
            }

            $email = $data['type'] == 0 ? $data['email'] : $user['email'];
            $mobile = $data['type'] == 1 ? $data['mobile'] : $user['mobile'];

            $user_create['id'] = $user['id'];
            //$user_create['username'] = isset($data['username']) ? $data['username'] : '';
            //$user_create['nickname'] = isset($data['username']) ? $data['username'] : '';
            $user_create['email'] = $email;
            $user_create['mobile'] = $mobile;
            $user_create['money'] = 0;
            $user_create['device'] = $user['device'];
            $user_create['system'] = $user['system'];
            $user_create['channel'] = $user['channel'];
            $user_create['invite'] = $user['invite'];
            $user_create['bind_invite'] = $invite;
            $user_create['rank'] = 0;
            $user_create['is_vip'] = 1;
            $user_create['expire_time'] = $user['expire_time'];
            $user_create['high_expire_time'] = $user['high_expire_time'];
            $user_create['token'] = md5(random(8));

            $user_create['role'] = 17;
            $user_create['status'] = 1;
            $user_create['last_login_time'] = time();
            $user_create['last_login_ip'] = request()->ip(1);
            $user_create['create_time'] = time();
            $user_create['update_time'] = time();
            $user_create['password'] = Hash::make((string)$data['password']);

            if (UserModel::update($user_create)) {

                if ($invite) {
                    $map = [];
                    $map[] = ['name', '=', 'invite_reward'];
                    $map[] = ['group', '=', 'vpn_config'];
                    $invite_reward = Config::where($map)->value('value');

                    $invite_data['uid'] = $user_invite['id'];
                    $invite_data['reg_uid'] = $user['id'];
                    $invite_data['invite_reward'] = $invite_reward;
                    $invite_data['invite'] = $invite;
                    $invite_data['device'] = $this->device;
                    $invite_data['system'] = $this->system;
                    $invite_data['version'] = $this->version;
                    $invite_data['channel'] = $this->channel;
                    $invite_data['ip'] = $this->ip;
                    $invite_data['remark'] = '';
                    $invite_data['status'] = 1;
                    $invite_data['create_time'] = time();
                    $invite_data['update_time'] = time();
                    $invite_create = Invite::create($invite_data);
                    if ($invite_create) {
                        UserModel::where('id', $user_invite['id'])
                            ->inc('money', $invite_reward)
                            ->update(['update_time' => time()]);
                    }
                }

                $res['uid'] = $user['id'];
                $res['username'] = $user['username'];
                $res['nickname'] = $user['nickname'];
                $res['email'] = $email;
                $res['mobile'] = $mobile;
                $res['money'] = $user['money'];
                $res['device'] = $user['device'];
                $res['system'] = $user['system'];
                $res['channel'] = $user['channel'];
                $res['invite'] = $user['invite'];
                $res['bind_invite'] = $invite;
                $res['rank'] = $user['rank'];
                $res['is_vip'] = 1;
                $res['expire_time'] = $user['expire_time'];
                $res['high_expire_time'] = $user['high_expire_time'];
                $res['token'] = $user_create['token'];

                $this->addDevice($res);
                $this->deleteCache(1, $res['uid']);
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '注册信息更新失败，请重新注册'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110004, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 获取验证码
     */
    public function getVerificationCode()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'type|类型' => 'require|in:0,1',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            if ($data['type'] == 1) {
                $validate = Validate::make([
                    'accounts|手机号' => 'require|regex:^1\d{10}',
                ]);
            }

            if ($data['type'] == 0) {
                $validate = Validate::make([
                    'accounts|邮箱' => 'require|email',
                ]);
            }

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $verify_code = VerifyCode::where(['ip' => Request::instance()->ip()])->order('create_time desc')->find();
            if ($verify_code && $verify_code['create_time'] > time() + 60) {
                return ['code' => 0, 'msg' => '请稍后再发送验证码'];
            }
            $verify_code = VerifyCode::where(['email_mobile' => $data['accounts']])->order('create_time desc')->find();
            if ($verify_code && $verify_code['create_time'] > time() + 60) {
                return ['code' => 0, 'msg' => '请稍后再发送验证码'];
            }

            $merchant_id = '55555555';
            $temp_map[] = ['email_mobile', '=', $data['accounts']];
            $temp_map[] = ['merchant_id', '=', $merchant_id];
            $temp_map[] = ['create_time', ['>=', time() - 3600], ['<', time()]];

            $count = VerifyCode::where($temp_map)->count();
            $hour_send_max_count = 5;
            if ($count >= $hour_send_max_count) {
                return ['code' => 0, 'msg' => "一个小时内最多只能发送{$hour_send_max_count}次"];
            }

            unset($temp_map);
            $temp_map[] = ['ip', '=', Request::instance()->ip()];
            $temp_map[] = ['merchant_id', '=', $merchant_id];
            $temp_map[] = ['create_time', ['>=', time() - 3600], ['<', time()]];
            $count = VerifyCode::where($temp_map)->count();
            if ($count >= $hour_send_max_count) {
                return ['code' => 0, 'msg' => "一个小时内最多只能发送{$hour_send_max_count}次"];
            }

            $data['id'] = date('YmdHis');
            $data['uid'] = $this->uid;
            $data['merchant_id'] = $merchant_id;
            $data['email_mobile'] = $data['accounts'];
            $data['verification_code'] = rand(100000, 999999);
            $data['type'] = $data['type'];
            $data['timeout'] = 3600;
            $data['remark'] = "验证码";
            $data['status'] = 1;
            $data['create_time'] = time();
            $data['device'] = $this->device;
            $data['system'] = $this->system;
            $data['version'] = $this->version;
            $data['channel'] = $this->channel;
            $data['ip'] = $this->ip;

            $info = VerifyCode::where(['id' => $data['id']])->find();
            if ($info) {
                return ['code' => 0, 'msg' => "请稍后再发送验证码"];
            }

            $ins = VerifyCode::create($data);
            if ($ins) {
                $body = "验证码是｛{$data['verification_code']}｝";
                // 邮箱
                if ($data['type'] == 0) {
                    $res = send_mail($data['accounts'], $data['accounts'], '验证码', $body);
                    if ($res === true) {
                        return ['code' => 1, 'msg' => "发送成功"];
                    }
                    vpn_error_log(110006, $data, $res);
                    return ['code' => 0, 'msg' => "发送失败"];
                }
                // 手机号
                if ($data['type'] == 1) {
                    $res = send_mobile($data['accounts'], $data['verification_code']);
                    if ($res === true) {
                        return ['code' => 1, 'msg' => "发送成功"];
                    }
                    vpn_error_log(110008, $data, $res);
                    return ['code' => 0, 'msg' => "发送失败"];
                }
            }

            return ['code' => 0, 'msg' => '系统异常'];
        } catch (\Exception $e) {
            vpn_error_log(110010, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 修改密码
     */
    public function editPwd()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'type|类型' => 'require|in:0,1',
                'password|密码' => 'require|length:6,20',
                'verification_code|验证码' => 'length:1,20',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            if ($data['type'] == 1) {
                $validate = Validate::make([
                    'accounts|手机号' => 'require|regex:^1\d{10}',
                ]);

                $map['mobile'] = $data['accounts'];
                $map['status'] = 1;

                $user = UserModel::where($map)->find();
                if (!$user) {
                    return ['code' => 0, 'msg' => '手机号不存在或被禁用'];
                }
            }

            if ($data['type'] == 0) {
                $validate = Validate::make([
                    'accounts|邮箱' => 'require|email',
                ]);

                $map['email'] = $data['accounts'];
                $map['status'] = 1;

                $user = UserModel::where($map)->find();
                if (!$user) {
                    return ['code' => 0, 'msg' => '邮箱不存在或被禁用'];
                }
            }

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            if ($data['type'] == 0 || $data['type'] == 1) {

                $validate = Validate::make([
                    'verification_code|验证码' => 'require|length:1,20',
                ]);

                if (!$validate->check($data)) {
                    return ['code' => 0, 'msg' => $validate->getError()];
                }

                $email_mobile = $data['accounts'];

                $verify = VerifyCode::where(['verification_code' => $data['verification_code'], 'email_mobile' => $email_mobile, 'status' => 1])->find();
                if (!$verify || $verify['timeout'] + $verify['create_time'] < time()) {
                    return ['code' => 0, 'msg' => '验证码不存在或验证码过期'];
                }
            }

            $user_update['id'] = $user['id'];
            $user_update['update_time'] = time();
            $user_update['token'] = md5(random(8));
            $user_update['password'] = Hash::make((string)$data['password']);

            if (UserModel::update($user_update)) {
                // 更新 
                $res['uid'] = $user['id'];
                $res['username'] = $user['username'];
                $res['nickname'] = $user['nickname'];
                $res['email'] = $user['email'];
                $res['mobile'] = $user['mobile'];
                $res['money'] = $user['money'];
                $res['device'] = $user['device'];
                $res['system'] = $user['system'];
                $res['channel'] = $user['channel'];
                $res['invite'] = $user['invite'];
                $res['bind_invite'] = $user['bind_invite'];
                $res['rank'] = $user['rank'];
                $res['is_vip'] = $user['is_vip'];
                $res['expire_time'] = $user['expire_time'];
                $res['high_expire_time'] = $user['high_expire_time'];
                $res['token'] = $user_update['token'];
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                // 更新信息失败
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110012, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 签到
     */
    public function signed()
    {
        try {
            $map1 = [
                ['create_time', '>', strtotime(date('Y-m-d'))],
                ['device', '=', $this->device],
            ];
            $map2 = [
                ['create_time', '>', strtotime(date('Y-m-d'))],
                ['uid', '=', $this->uid],
            ];
            $find = Signed::whereOr([$map1, $map2])->find();
            if ($find) {
                return ['code' => 0, 'msg' => '今天已经签到'];
            }

            $map = [];
            $map[] = ['name', '=', 'delivery_time'];
            $map[] = ['group', '=', 'vpn_config'];
            $delivery_time = Config::where($map)->value('value');

            $user['expire_time'] = $this->user['expire_time'] ? $this->user['expire_time'] : 0;
            if ($user['expire_time'] > time()) {
                $user['expire_time'] = $delivery_time + $user['expire_time'];
            } else {
                $user['expire_time'] = $delivery_time + time();
            }

            $signed['uid'] = $this->uid;
            $signed['device'] = $this->device;
            $signed['system'] = $this->system;
            $signed['version'] = $this->version;
            $signed['channel'] = $this->channel;
            $signed['ip'] = $this->ip;
            $signed['time'] = $delivery_time;
            $signed['expire_time'] = $user['expire_time'];
            $signed['status'] = 1;
            $signed['create_time'] = time();
            $signed['update_time'] = time();

            if (Signed::create($signed)) {
                $user_update['expire_time'] = $user['expire_time'];
                $user_update['update_time'] = time();
                $update = UserModel::where(['id' => $this->uid])->update($user_update);
                if ($update) {
                    $res['uid'] = $this->uid;
                    $res['expire_time'] = $user['expire_time'];

                    $this->deleteCache(1, $res['uid']);
                    return ['code' => 1, 'msg' => '成功', 'data' => $res];
                }
            }

            return ['code' => 0, 'msg' => '签到失败'];
        } catch (\Exception $e) {
            vpn_error_log(110014, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 邀请列表
     */
    public function invite()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'limit|数量' => 'require|number|between:1,50',
                'page|分页' => 'require|number',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $map = [];
            $map[] = ['uid', '=', $this->uid];

            $res = Invite::where($map)
                ->limit($data['limit'])
                ->page($data['page'])
                ->order(['create_time' => 'desc'])
                ->select();

            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110016, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 系统设置配置
     */
    public function service()
    {
        try {
            $vpn_service = 'vpn_service_config';
            $now_vpn_service = $this->redis->get($vpn_service);
            if ($now_vpn_service) {
                $res = $now_vpn_service;
            } else {
                $res = Service::where(['status' => 1])
                    ->order(['sort' => 'asc', 'create_time' => 'desc'])
                    ->select();
                $this->redis->set($vpn_service, $res, $this->expire);
            }

            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110018, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 链接列表
     */
    public function link()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'limit|数量' => 'require|number|between:1,100',
                'page|分页' => 'require|number',
                'mode|模式' => 'length:1,50',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $map = [];
            $map[] = ['status', '=', 1];
            if (isset($data['mode']) && $data['mode'] != '') {
                $map[] = ['mode', '=', $data['mode']];
            }

            $res = Link::where($map)
                ->limit($data['limit'])
                ->page($data['page'])
                ->order(['sort' => 'asc', 'create_time' => 'desc'])
                ->select();

            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110020, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 节点列表
     */
    public function node()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'limit|数量' => 'require|number|between:1,100',
                'page|分页' => 'require|number',
                'assort|节点类型' => 'length:1,50',
                'rank|等级' => 'length:1,10',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $expire_time = 60;

            $rank = 0;
            $user['expire_time'] = $this->user['expire_time'] ? $this->user['expire_time'] : 0;
            $user['high_expire_time'] = $this->user['high_expire_time'] ? $this->user['high_expire_time'] : 0;
            if ($user['expire_time'] > time()) {
                $rank = 1;
            }
            if ($user['high_expire_time'] > time()) {
                $rank = 2;
            }

            $map = [];
            $map[] = ['status', '=', 1];
            $map[] = ['rank', '<=', $rank];
            if (isset($data['assort']) && $data['assort'] != '') {
                $map[] = ['assort', '=', $data['assort']];
            }

            $assort = isset($data['assort']) ? isset($data['assort']) : '';
            $string = 'vpn_' . $rank . '_' . $data['limit'] . '_' . $data['page'] . '_' . $assort;
            $now_string = $this->redis->get($string);
            if ($now_string) {
                $res = $now_string;
            } else {
                $res = Node::where($map)
                    ->limit($data['limit'])
                    ->page($data['page'])
                    ->order(['sort' => 'asc', 'create_time' => 'desc'])
                    ->select();
                $res = $res->toArray();
                if ($res) {
                    foreach ($res as &$subArray) {
                        foreach ($subArray as $key => $value) {
                            if (empty($value)) {
                                $subArray[$key] = '';
                            }
                        }
                    }
                }

                $this->redis->set($string, $res, $expire_time);
            }

            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110022, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 支付方式
     */
    public function payWay()
    {
        try {
            $map[] = ['name', '=', 'pay_way'];
            $map[] = ['group', '=', 'vpn_config'];
            $res = Config::where($map)->value('value');
            $array = preg_split('/[,;\r\n]+/', trim($res, ",;\r\n"));
            $value = array();
            foreach ($array as $val) {
                list($k, $v) = explode(':', $val);
                $value[$k] = $v;
            }
            $res = [];
            $i = 0;
            foreach ($value as $k => $v) {
                $res[$i]['k'] = $k;
                $res[$i]['v'] = $v;
                $i++;
            }
            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110024, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 商品列表
     */
    public function payShop()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $map = [];
            $map[] = ['status', '=', 1];
            if (isset($data['mode']) && $data['mode'] != '') {
                $map[] = ['mode', '=', $data['mode']];
            }

            $res = Shop::where($map)
                ->order(['sort' => 'asc', 'create_time' => 'desc'])
                ->select();

            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110026, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 创建订单
     */
    public function orderCreate()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'uid|用户id' => 'require',
                'cash|金额' => 'require|min:0.01|max:10000',
                'way|支付方式' => 'require',
                'cid|商品id' => 'require',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $shop = Shop::where(['cid' => $data['cid']])->find();
            if ($shop['cash'] != $data['cash']) {
                return ['code' => 0, 'msg' => '金额有误'];
            }

            $url = request()->domain() . '/api.php/order/create';         // 接口请求地址	

            switch ($data['way']) {
                case 'zfbpay':
                    $type = 'alipay_h5';
                    break;
                case 'wxpay':
                    $type = 'wechat_h5';
                    break;
                case 'yhkpay':
                    $type = 'wangyin';
                    break;
                case 'apple':
                    $type = 'apple';
                    break;
                case 'google':
                    $type = 'google';
                    break;
                default:
                    $type = 'alipay_h5';
            }

            $data['version'] = '1.0';                                           // 版本号
            $data['merchant_id'] = 55555555;                                    // 商户号
            $data['merchant_order_id'] = date('YmdHis') . rand(100000, 999999); // 商户订单号
            $data['app_id'] = 0;                                                // 应用id
            $data['cash'] = $data['cash'];                                      // 金额（元） 
            $data['type'] = $type;                                              // 支付类型 wechat_h5 alipay_h5 wangyin alipay_scan_code wechat_scan_code
            $data['trade_type'] = 'consumption';                                // 交易类型
            $data['body'] = '商品名称';                                          // 商品名称
            $data['name'] = '0';                                                // 姓名
            $data['id_card'] = '0';                                             // 身份证号
            $data['mobile'] = '0';                                              // 手机号
            $data['start_time'] = time();                                       // 订单开始时间:时间戳
            $data['return_url'] = 'https://www.baidu.com';                      // 支付成功服务器返回地址
            $data['notify_url'] = request()->domain() . '/success.html';        // 支付成功页面通知地址
            $data['ip'] = request()->ip();                                      // IP地址
            $data['user_id'] = $this->uid;                                      // 用户ID
            $data['channel_id'] = $this->channel ? $this->channel : 0;          // 渠道ID
            $data['system'] = $this->system;                                    // 系统
            $data['cid'] = $data['cid'];                                        // 商品id
            $data['format'] = 'json';                                           // 返回格式
            $data['sign_type'] = 'md5';                                         // 签名类型
            $data['business_type'] = 'B2C';                                     // 业务类型
            $data['bank_code'] = "ICBC";                                        // 银行编号
            $data['extra'] = json_encode($shop);                                // 商户自定义备注（原值返回）
            $data['random_string'] = date('YmdHis') . rand(100000, 999999);     // 随机字符串

            $key = db('payment_merchant_config')->where(['id' => $data['merchant_id']])->value('key');
            $data['sign'] = md5('merchant_id=' . $data['merchant_id'] . '&merchant_order_id=' . $data['merchant_order_id'] . '&cash=' . $data['cash'] . '&type=' . $data['type'] . '&return_url=' . $data['return_url'] . '&notify_url=' . $data['notify_url'] . '&ip=' . $data['ip'] . '&start_time=' . $data['start_time'] . '&random_string=' . $data['random_string'] . '&key=' . $key);

            $resdata = go_curl($url, $data, 'post', 10);
            $resarray = json_decode($resdata, true);

            if ($resarray['code'] == 10000) {
                $res['pay_url'] = $resarray['pay_url'];
                $res['order_id'] = $resarray['order_id'];
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => $resarray['msg']];
            }
        } catch (\Exception $e) {
            vpn_error_log(110028, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 苹果收据
     */
    public function appleReceipt()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'order_id|订单号' => 'require',
                'receipt_data|苹果收据' => 'require',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            // 1个订单号5秒接收一次
            $order_id_verify = 'vpn_order_id_verify_' . $data['order_id'];
            $now_order_id_verify = $this->redis->get($order_id_verify);
            if ($now_order_id_verify) {
                return ['code' => 0, 'msg' => '稍后再试'];
            } else {
                $this->redis->set($order_id_verify, 1, 5);
            }

            $map[] = ['order_id', '=', $data['order_id']];

            $res = PaymentOrder::where($map)->find();
            if ($res && $res['status'] == 1) {

                if ($res['type'] != 'apple') {
                    return ['code' => 0, 'msg' => '不是苹果支付'];
                }

                $sandbox = 1;
                // 正式购买地址 沙盒购买地址
                $url_buy = "https://buy.itunes.apple.com/verifyReceipt";
                $url_sandbox = "https://sandbox.itunes.apple.com/verifyReceipt";
                $url = $sandbox ? $url_sandbox : $url_buy;

                // 这里本来是需要base64加密的，我这里没有加密的原因是客户端返回服务器端之前，已经作加密处理      
                $apple_data = array('receipt-data' => $data['receipt_data']);
                $apple_data = json_encode($apple_data);

                $resdata = go_curl($url, $apple_data, 'post', 10);
                $resarray = json_decode($resdata, true);

                if (isset($resarray['status']) && $resarray['status'] == 0) {

                    $other_order_id_find = PaymentOrder::where(['other_order_id' => $resarray['receipt']['in_app'][0]['transaction_id']])->find();
                    if ($other_order_id_find) {
                        vpn_error_log(1100345, input());
                        return ['code' => 0, 'msg' => '苹果支付异常'];
                    }

                    $update['status'] = 2;
                    $update['other_order_id'] = $resarray['receipt']['in_app'][0]['transaction_id'];
                    $update['notify_param'] = $resdata;
                    $update['update_time'] = time();
                    $order_update = PaymentOrder::where($map)->update($update);
                    if ($order_update) {

                        $shop = Shop::where(['cid' => $res['shop_id']])->find();

                        $user_update = [];
                        $day = $shop['day'] * 86400;
                        if ($shop['mode'] == 0) {
                            $user['expire_time'] = $this->user['expire_time'] ? $this->user['expire_time'] : 0;
                            if ($user['expire_time'] < time()) {
                                $update_time = time() + $day;
                            } else {
                                $update_time = $user['expire_time'] + $day;
                            }
                            $user_update['expire_time'] = $update_time;
                        }

                        if ($shop['mode'] == 1) {
                            $user['high_expire_time'] = $this->user['high_expire_time'] ? $this->user['high_expire_time'] : 0;
                            if ($user['high_expire_time'] < time()) {
                                $update_time = time() + $day;
                            } else {
                                $update_time = $user['high_expire_time'] + $day;
                            }
                            $user_update['high_expire_time'] = $update_time;
                        }
                        $user_update['update_time'] = time();
                        $user_update_status = UserModel::where(['id' => $res['user_id']])->update($user_update);
                        if ($user_update_status) {

                            $res = [];
                            $res['uid'] = $this->user['id'];
                            $res['username'] = $this->user['username'];
                            $res['nickname'] = $this->user['nickname'];
                            $res['email'] = $this->user['email'];
                            $res['mobile'] = $this->user['mobile'];
                            $res['money'] = $this->user['money'];
                            $res['device'] = $this->device;
                            $res['system'] = $this->system;
                            $res['channel'] = $this->channel;
                            $res['invite'] = $this->user['invite'];
                            $res['bind_invite'] = $this->user['bind_invite'];
                            $res['rank'] = $this->user['rank'];
                            $res['is_vip'] = $this->user['is_vip'];
                            $res['expire_time'] = $shop['mode'] == 0 ? $user_update['expire_time'] : $this->user['expire_time'];
                            $res['high_expire_time'] = $shop['mode'] == 1 ? $user_update['high_expire_time'] : $this->user['high_expire_time'];
                            $res['token'] = $this->user['token'];

                            return ['code' => 1, 'msg' => '成功', 'data' => $res];
                        }
                        vpn_error_log(110034, input());
                        return ['code' => 0, 'msg' => '订单更新失败'];
                    } else {
                        vpn_error_log(110032, input());
                        return ['code' => 0, 'msg' => '订单更新失败'];
                    }
                } else {
                    return ['code' => 0, 'msg' => '没有支付'];
                }
            } else {
                vpn_error_log(110030, input());
                return ['code' => 0, 'msg' => '订单状态有误'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110036, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 谷歌收据
     */
    public function googleReceipt()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'order_id|订单号' => 'require',
                'google_order_id|谷歌订单号' => 'require',
                'package_name|包名' => 'require',
                'product_id|产品id' => 'require',
                'purchase_token|谷歌收据' => 'require',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            // 1个订单号5秒接收一次
            $order_id_verify = 'vpn_order_id_verify_' . $data['order_id'];
            $now_order_id_verify = $this->redis->get($order_id_verify);
            if ($now_order_id_verify) {
                return ['code' => 0, 'msg' => '稍后再试'];
            } else {
                $this->redis->set($order_id_verify, 1, 5);
            }

            $map[] = ['order_id', '=', $data['order_id']];

            $res = PaymentOrder::where($map)->find();
            if ($res && $res['status'] == 1) {

                if ($res['type'] != 'google') {
                    return ['code' => 0, 'msg' => '不是谷歌支付'];
                }

                $params = [
                    'grant_type' => 'refresh_token',
                    'refresh_token' => '1//0ePYHHnaoDk6lCgYIARAAGA4SNwF-L9Ir9RrneOvIsD8lWzW1aU0xP5HAo3nCBSbwJse0NDfv77_abQ7iH3W9g3yNU-zLVOqWS60',
                    'client_id' => '734626261272-0rsec0rfkjdsla5vo9qdposlhph2oafj.apps.googleusercontent.com',
                    'client_secret' => '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',
                    'redirect_uri' => 'https://lt.246.ink/api.php/test/log',
                ];

                $url = 'https://accounts.google.com/o/oauth2/token';

                $resdata = go_curl($url, $params, 'post', 10);
                $resarray = json_decode($resdata, true);
                // if (isset($resarray['access_token'])) {
                //     $access_token = $resarray['access_token'];
                // } else {
                //     vpn_error_log(1100345, input());
                //     return ['code' => 0, 'msg' => '异常'];
                // }

                $packageName = $data['package_name'];
                $productId = $data['product_id'];
                $purchaseToken = $data['purchase_token'];
                $apiKey = "your_api_key";
                $resarray['orderId'] = $data['order_id'];
                // 创建验证请求的 URL
                $url = "https://www.googleapis.com/androidpublisher/v3/applications/{$packageName}/purchases/products/{$productId}/tokens/{$purchaseToken}?access_token={$apiKey}";

                $resdata = go_curl($url, '', 'get', 1);
                $resarray = json_decode($resdata, true);
                if (isset($resarray['consumptionState']) && $resarray['consumptionState'] == 0 || true) {

                    $other_order_id_find = PaymentOrder::where(['other_order_id' => $data['google_order_id']])->find();
                    if ($other_order_id_find) {
                        vpn_error_log(1100345, input());
                        return ['code' => 0, 'msg' => '谷歌支付异常'];
                    }

                    $resdata = json_encode($data);
                    $update['status'] = 2;
                    $update['other_order_id'] = $data['google_order_id'];
                    $update['notify_param'] = $resdata;
                    $update['update_time'] = time();
                    $order_update = PaymentOrder::where($map)->update($update);
                    if ($order_update) {

                        $shop = Shop::where(['cid' => $res['shop_id']])->find();

                        $user_update = [];
                        $day = $shop['day'] * 86400;
                        if ($shop['mode'] == 0) {
                            $user['expire_time'] = $this->user['expire_time'] ? $this->user['expire_time'] : 0;
                            if ($user['expire_time'] < time()) {
                                $update_time = time() + $day;
                            } else {
                                $update_time = $user['expire_time'] + $day;
                            }
                            $user_update['expire_time'] = $update_time;
                        }

                        if ($shop['mode'] == 1) {
                            $user['high_expire_time'] = $this->user['high_expire_time'] ? $this->user['high_expire_time'] : 0;
                            if ($user['high_expire_time'] < time()) {
                                $update_time = time() + $day;
                            } else {
                                $update_time = $user['high_expire_time'] + $day;
                            }
                            $user_update['high_expire_time'] = $update_time;
                        }
                        $user_update['update_time'] = time();
                        $user_update_status = UserModel::where(['id' => $res['user_id']])->update($user_update);
                        if ($user_update_status) {

                            $res = [];
                            $res['uid'] = $this->user['id'];
                            $res['username'] = $this->user['username'];
                            $res['nickname'] = $this->user['nickname'];
                            $res['email'] = $this->user['email'];
                            $res['mobile'] = $this->user['mobile'];
                            $res['money'] = $this->user['money'];
                            $res['device'] = $this->device;
                            $res['system'] = $this->system;
                            $res['channel'] = $this->channel;
                            $res['invite'] = $this->user['invite'];
                            $res['bind_invite'] = $this->user['bind_invite'];
                            $res['rank'] = $this->user['rank'];
                            $res['is_vip'] = $this->user['is_vip'];
                            $res['expire_time'] = $shop['mode'] == 0 ? $user_update['expire_time'] : $this->user['expire_time'];
                            $res['high_expire_time'] = $shop['mode'] == 1 ? $user_update['high_expire_time'] : $this->user['high_expire_time'];
                            $res['token'] = $this->user['token'];

                            return ['code' => 1, 'msg' => '成功', 'data' => $res];
                        }
                        vpn_error_log(110034, input());
                        return ['code' => 0, 'msg' => '订单更新失败'];
                    } else {
                        vpn_error_log(110032, input());
                        return ['code' => 0, 'msg' => '订单更新失败'];
                    }
                } else {
                    return ['code' => 0, 'msg' => '没有支付'];
                }
            } else {
                vpn_error_log(110030, input());
                return ['code' => 0, 'msg' => '订单状态有误'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110036, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 订单列表
     */
    public function orderList()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'uid|用户id' => 'require',
                'status|状态' => '',
                'limit|数量' => 'require|number|between:1,20',
                'page|分页' => 'require|number',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $map = [];
            if (isset($data['status']) && $data['status'] != '') {
                $map[] = ['status', '=', $data['status']];
            }

            $map[] = ['user_id', '=', $this->uid];

            $res = PaymentOrder::where($map)
                ->field('order_id,status,type,cash,now_cash,create_time,update_time')
                ->limit($data['limit'])
                ->page($data['page'])
                ->order(['create_time' => 'desc'])
                ->select();

            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110038, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 添加设备
     */
    protected function addDevice($data = [])
    {
        try {
            if ($data) {
                $map[] = ['uid', '=', $data['uid']];
                $map[] = ['device', '=', $data['device']];
                $find = Device::where($map)->find();
                if ($find) {
                    $device['update_time'] = time();
                    Device::where($map)->update($device);
                } else {
                    $device['uid'] = $data['uid'];
                    $device['model'] = $this->model;
                    $device['device'] = $this->device;
                    $device['system'] = $this->system;
                    $device['version'] = $this->version;
                    $device['channel'] = $this->channel;
                    $device['ip'] = $this->ip;
                    $device['status'] = 1;
                    $device['create_time'] = time();
                    $device['update_time'] = time();
                    Device::create($device);
                }
            }
        } catch (\Exception $e) {
            vpn_error_log(110040, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 删除设备
     */
    public function deleteDevice()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'device|设备' => 'require',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $map[] = ['uid', '=', $this->uid];
            $map[] = ['device', '=', $data['device']];

            $res = Device::where($map)->delete();

            if ($res) {
                return ['code' => 1, 'msg' => '成功'];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110042, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 反馈
     */
    public function feedback()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'mode|类型' => 'require|number',
                'contact|联系方式' => 'require|length:1,100',
                'message|留言' => 'require|length:1,1000',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $res = Feedback::where(['uid' => $this->uid])
                ->order(['create_time' => 'desc'])
                ->find();
            if ($res) {
                if ($res['create_time'] + 300 > time()) {
                    return ['code' => 0, 'msg' => '请五分钟后发送'];
                }
            }

            $arr['uid'] = $this->uid;
            $arr['device'] = $this->device;
            $arr['system'] = $this->system;
            $arr['version'] = $this->version;
            $arr['channel'] = $this->channel;
            $arr['ip'] = $this->ip;
            $arr['mode'] = $data['mode'];
            $arr['contact'] = htmlentities($data['contact']);
            $arr['message'] = htmlentities($data['message']);
            $arr['status'] = 1;
            $arr['create_time'] = time();
            $arr['update_time'] = time();
            if (Feedback::create($arr)) {
                return ['code' => 1, 'msg' => '成功'];
            }
            return ['code' => 0, 'msg' => '失败'];
        } catch (\Exception $e) {
            vpn_error_log(110044, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 反馈列表
     */
    public function feedbackList()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'limit|数量' => 'require|number|between:1,20',
                'page|分页' => 'require|number',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $map = [];
            $map[] = ['uid', '=', $this->uid];
            $map[] = ['status', '=', 1];

            $res = Feedback::where($map)
                ->limit($data['limit'])
                ->page($data['page'])
                ->order(['create_time' => 'desc'])
                ->select();

            if ($res) {
                return ['code' => 1, 'msg' => '成功', 'data' => $res];
            } else {
                return ['code' => 0, 'msg' => '失败'];
            }
        } catch (\Exception $e) {
            vpn_error_log(110046, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 流量
     */
    public function flow()
    {
        try {
            // 表单数据
            $data = $this->request->post();

            $validate = Validate::make([
                'node_id|节点id' => 'require|number',
                'upload|上传' => 'require|number',
                'download|下载' => 'require|number',
            ]);

            if (!$validate->check($data)) {
                return ['code' => 0, 'msg' => $validate->getError()];
            }

            $node = Node::where(['cid' => $data['node_id']])->find();

            $arr['uid'] = $this->uid;
            $arr['device'] = $this->device;
            $arr['system'] = $this->system;
            $arr['version'] = $this->version;
            $arr['channel'] = $this->channel;
            $arr['ip'] = $this->ip;
            $arr['node_id'] = $data['node_id'];
            $arr['upload'] = $data['upload'];
            $arr['download'] = $data['download'];
            $arr['node_info'] = $node;
            $arr['status'] = 1;
            $arr['create_time'] = time();
            $arr['update_time'] = time();
            if (Flow::create($arr)) {
                return ['code' => 1, 'msg' => '成功'];
            }
            return ['code' => 0, 'msg' => '失败'];
        } catch (\Exception $e) {
            vpn_error_log(110048, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 删除缓存
     */
    protected function deleteCache($id = '', $uid = '')
    {
        try {
            switch ($id) {
                    // 删除用户缓存
                case '1':
                    $user_info_id = 'vpn_user_info_id_' . $uid;
                    $this->redis->pull($user_info_id);
                    // 订单已经支付完成
                case '2':
                    //payment_error_log(620005, $order_arr, "可能是第三方用了(多台服务器通知)，也有可能是第一次支付公司（{$order_arr['company']}）通知出现异常，状态已经修改，但是没有返回success", false);
                    return 'success';
                default:
                    // 状态错误
                    //vpn_error_log(110048, input());
            }
        } catch (\Exception $e) {
            vpn_error_log(110050, input(), $e->getMessage());
            return ['code' => 555, 'msg' => '系统异常'];
        }
    }

    /**
     * 用户在线
     */
    protected function online()
    {
        $expire_time = 1800;

        $online_uid = 'vpn_online_' . $this->uid;
        $now_online_uid = $this->redis->get($online_uid);
        if ($now_online_uid) {
        } else {
            $user_update['id'] = $this->uid;
            $user_update['last_login_time'] = time();
            $user_update['last_login_ip'] = request()->ip(1);
            $user_update['update_time'] = time();
            UserModel::update($user_update);
            $this->redis->set($online_uid, 1, $expire_time);
        }
    }

    /**
     * ip黑名单
     */
    protected function ipblack()
    {
        $expire_time = 1800;

        // 单个ip黑名单
        $ipblack_data_0 = [];
        $ipblack_0 = 'vpn_ipblack_0';
        $now_ipblack_0 = $this->redis->get($ipblack_0);
        if ($now_ipblack_0) {
            $ipblack_data_0 = $now_ipblack_0;
        } else {
            $ipblack_interval_0 = 'vpn_ipblack_interval_0';
            $now_ipblack_interval_0 = $this->redis->get($ipblack_interval_0);
            if ($now_ipblack_interval_0) {
            } else {
                $this->redis->set($ipblack_interval_0, 1, $expire_time);

                $ipblack_data_0 = Ipblacklist::where(['mode' => 0, 'status' => 1])->column('start_ip');
                $this->redis->set($ipblack_0, $ipblack_data_0, $expire_time);
            }
        }

        if ($ipblack_data_0) {
            if (in_array($this->ip, $ipblack_data_0)) {
                json(['code' => 0, 'msg' => 'ip黑名单'])->send();
                exit;
            }
        }

        // 区间ip黑名单
        $ipblack_data_1 = [];
        $ipblack_1 = 'vpn_ipblack_1';
        $now_ipblack_1 = $this->redis->get($ipblack_1);
        if ($now_ipblack_1) {
            $ipblack_data_1 = $now_ipblack_1;
        } else {
            $ipblack_interval_1 = 'vpn_ipblack_interval_1';
            $now_ipblack_interval_1 = $this->redis->get($ipblack_interval_1);
            if ($now_ipblack_interval_1) {
            } else {
                $this->redis->set($ipblack_interval_1, 1, $expire_time);

                $ipblack_data_1 = Ipblacklist::where(['mode' => 1, 'status' => 1])->column('start_ip,end_ip');
                $this->redis->set($ipblack_1, $ipblack_data_1, $expire_time);
            }
        }

        if ($ipblack_data_1) {
            foreach ($ipblack_data_1 as $k => $v) {
                $start_ip = ip2long($k);
                $end_ip = ip2long($v);
                $now_ip = ip2long($this->ip);
                // 检查目标 IP 是否在 IP 范围内
                if ($now_ip >= $start_ip && $now_ip <= $end_ip) {
                    json(['code' => 0, 'msg' => 'ip黑名单1'])->send();
                    exit;
                }
            }
        }
    }
}
